<template>
  <div v-if="open" class="mask" @click="$emit('close')" @wheel.stop.prevent></div>
  <aside v-if="open" class="drawer glass" @click.stop @wheel.stop>
    <header class="hdr glass">
      <h3>设置</h3>
      <button class="close" @click="emit('close')">✖</button>
    </header>

    <div v-if="!ready" class="loading">正在载入设置…</div>

    <div v-else class="panel">
      <nav class="side glass">
        <button class="item" :class="{on: tab==='general'}" @click="tab='general'">常规设置</button>
        <button class="item" :class="{on: tab==='data'}" @click="tab='data'">数据</button>
        <button class="item" :class="{on: tab==='background'}" @click="tab='background'">背景</button>
        <button class="item" :class="{on: tab==='about'}" @click="tab='about'">关于</button>
      </nav>
      <div class="content">
      <section class="sec glass" v-show="tab==='general'">
        <h4>常规</h4>
        <div class="row">
          <label>打开方式</label>
          <div class="seg" role="tablist" aria-label="打开方式">
            <button type="button" class="seg-item" :class="{on: settings.settings.openMode==='current'}" @click="setOpenMode('current')" role="tab" :aria-selected="settings.settings.openMode==='current'">当前标签</button>
            <button type="button" class="seg-item" :class="{on: settings.settings.openMode==='newtab'}" @click="setOpenMode('newtab')" role="tab" :aria-selected="settings.settings.openMode==='newtab'">新标签</button>
          </div>
        </div>
        
        <div class="row">
          <label>显示名称</label>
          <input type="checkbox" v-model="settings.settings.showName" @change="settings.persist()" />
        </div>
        <div class="row">
          <label>启用浮动按钮组</label>
          <input type="checkbox" v-model="settings.settings.fabEnabled" @change="settings.persist()" />
          <span class="tip">控制在其它网页右下角显示二维码/返回顶部/收藏按钮</span>
        </div>
        <div class="row">
          <label>列数</label>
          <input type="range" min="3" max="12" step="1" v-model.number="settings.settings.columns" @input="debouncedPersist" />
          <span>{{ settings.settings.columns }}</span>
          <button class="btn outline reset" @click="resetColumns" title="恢复默认列数">重置</button>
        </div>
        <div class="row">
          <label>圆角(px)</label>
          <input type="range" min="0" max="28" step="1" v-model.number="settings.settings.radius" @input="debouncedPersist" />
          <span>{{ settings.settings.radius }}</span>
          <button class="btn outline reset" @click="resetRadius" title="恢复默认圆角">重置</button>
        </div>
        <div class="row">
          <label>卡片透明度</label>
          <input type="range" min="0.2" max="1" step="0.02" v-model.number="settings.settings.cardOpacity" @input="debouncedPersist" />
          <span>{{ (settings.settings.cardOpacity ?? (settings.settings.theme==='light'?0.96:0.50)).toFixed(2) }}</span>
          <button class="btn outline reset" @click="resetCardOpacity" title="恢复按主题默认(深色0.50/浅色0.96)">重置</button>
        </div>
        <div class="row">
          <label>图标大小(px)</label>
          <input type="range" min="32" max="72" step="2" v-model.number="settings.settings.iconPx" @input="debouncedPersist" />
          <span>{{ settings.settings.iconPx || iconSizeToPx(settings.settings.iconSize) }}</span>
          <button class="btn outline reset" @click="resetIconPx" title="恢复由“图标大小”控制">重置</button>
        </div>
        <div class="row">
          <label>列表最大宽度(px)</label>
          <input type="range" min="960" max="1600" step="40" v-model.number="settings.settings.contentMaxWidth" @input="debouncedPersist" />
          <span>{{ settings.settings.contentMaxWidth || 1440 }}</span>
          <button class="btn outline reset" @click="resetContentMaxWidth" title="恢复默认宽度(1440)">重置</button>
        </div>
        
      </section>
      <section class="sec glass" v-show="tab==='data'">
        <h4>数据</h4>
        <div class="row">
          <div class="actions">
            <button class="btn solid wide" @click="doExport">导出备份</button>
            <button class="btn solid wide" @click="importInput?.click()">导入备份</button>
            <input ref="importInput" type="file" accept="application/json,.json,.data" @change="doImport" style="display:none" />
          </div>
          <span class="filename">{{ importFileName || '未选择任何文件' }}</span>
        </div>
        <div class="row">
          <label>站点缓存</label>
          <button class="btn outline" @click="clearSiteCache">清空站点缓存</button>
          <span class="tip">清理已抓取的标题与图标缓存（7天内的命中将失效）</span>
        </div>
      </section>
      <section class="sec glass" v-show="tab==='background'">
        <h4>背景</h4>
        <div class="row">
          <label>当前</label>
          <span class="bg-tip">{{ settings.settings.backgroundDataUrl ? '已设置自定义背景' : '未设置' }}</span>
        </div>
        <div class="row tight">
          <label>来源</label>
          <div class="seg" role="tablist" aria-label="背景来源">
            <button type="button" class="seg-item" :class="{on: bgMode==='upload'}" @click="bgMode='upload'" role="tab" :aria-selected="bgMode==='upload'">本地图片</button>
            <button type="button" class="seg-item" :class="{on: bgMode==='url'}" @click="bgMode='url'" role="tab" :aria-selected="bgMode==='url'">远程图片</button>
          </div>
        </div>
        <div v-if="bgMode==='upload'" class="row tight">
          <label>上传</label>
          <button class="btn outline" @click="bgInput?.click()">选择文件</button>
          <input ref="bgInput" type="file" accept="image/*" @change="onPickBg" style="display:none" />
          <span class="filename">{{ bgFileName || '未选择任何文件' }}</span>
          <button class="btn outline" @click="clearBg">清除背景</button>
        </div>
        <div v-else class="row tight col">
          <label>地址</label>
          <input class="url" type="text" v-model="bgUrl" placeholder="支持 data:image/... 或 http(s) 图片链接" />
          <div class="actions">
            <button class="btn solid" @click="applyBgUrl">应用</button>
            <button class="btn outline" @click="clearBg">清除背景</button>
          </div>
          <small class="tip">提示：使用 http(s) 将发起网络请求并缓存为本地 dataURL；如需纯离线请使用 data:image/... 或“本地图片”。</small>
        </div>
        <div class="row">
          <label>遮罩强度</label>
          <input type="range" min="0" max="0.6" step="0.02" v-model.number="settings.settings.backgroundOverlay" @input="debouncedPersist" />
          <span>{{ (settings.settings.backgroundOverlay ?? 0).toFixed(2) }}</span>
        </div>
        <div class="row">
          <label>模糊(px)</label>
          <input type="range" min="0" max="20" step="1" v-model.number="settings.settings.backgroundBlur" @input="debouncedPersist" />
          <span>{{ settings.settings.backgroundBlur ?? 0 }}</span>
        </div>
        <div class="row">
          <label>位置</label>
          <select v-model="settings.settings.backgroundPosition" @change="settings.persist()">
            <option value="center">居中</option>
            <option value="top">顶部</option>
            <option value="bottom">底部</option>
            <option value="left">左侧</option>
            <option value="right">右侧</option>
          </select>
        </div>
        <div class="row">
          <label>填充</label>
          <select v-model="settings.settings.backgroundSize" @change="settings.persist()">
            <option value="cover">铺满(裁剪)</option>
            <option value="contain">适应(留边)</option>
            <option value="auto">原尺寸</option>
            <option value="tile">平铺</option>
          </select>
        </div>
      </section>
      <section class="sec glass" v-show="tab==='about'">
        <h4>关于</h4>
        <p>GCE启动器 v1.0.0 · 仅本地存储、不联网</p>
        <p>POWER BY GLQ @ 2025</p>
        <p>powerglq@163.com</p>
        <p><a href="https://gitee.com/coolteam/gce/blob/master/index.html" target="_blank" class="btn solid wide">更多常用工具</a></p>
      </section>
      </div>
    </div>
  </aside>
</template>
<script setup lang="ts">
import { onMounted, computed, watch } from 'vue';
import { useSettings } from '../../core/store/useSettings';
import { exportBackup, importBackup } from '../../core/utils/backup';
import { ref, watchEffect } from 'vue';
import { useBookmarks } from '../../core/store/useBookmarks';
import { useEngines } from '../../core/store/useEngines';
import { getRoot } from '../../core/store/useStorage';
import { debounce } from '../../core/utils/debounce';

const props = defineProps<{ open: boolean }>();
const emit = defineEmits<{ (e:'close'): void }>();
const settings = useSettings();
const bm = useBookmarks();
const engines = useEngines();

// 已移除“默认分组”功能


const bgUrl = ref('');
const bgMode = ref<'upload'|'url'>('upload');
const importFileName = ref('');
const bgFileName = ref('');
const importInput = ref<HTMLInputElement|null>(null);
const bgInput = ref<HTMLInputElement|null>(null);
// 左侧分类 tab 状态（本地持久化，避免每次打开重置）
type TabKey = 'general' | 'data' | 'background' | 'about';
const TAB_STORAGE_KEY = 'wetab_settings_tab';
const tab = ref<TabKey>((localStorage.getItem(TAB_STORAGE_KEY) as TabKey) || 'general');
watchEffect(()=>{ try{ localStorage.setItem(TAB_STORAGE_KEY, tab.value); }catch{} });
// 移除与默认分组相关的校验逻辑
async function onPickBg(e: Event){
  const f = (e.target as HTMLInputElement).files?.[0];
  if(!f) return;
  bgFileName.value = f.name || '';
  const reader = new FileReader();
  reader.onload = async ()=>{
    settings.settings.backgroundDataUrl = String(reader.result || '');
    await settings.persist();
  };
  reader.readAsDataURL(f);
}

async function clearSiteCache(){
  const key = 'gce_site_cache_v1';
  try{
    const st: any = (globalThis as any).chrome?.storage?.local;
    if(st){ await new Promise<void>(resolve=> st.remove(key, ()=> resolve())); }
  }catch{}
  try{ localStorage.removeItem(key); }catch{}
  try{ (window as any).gceToast?.('已清空站点缓存'); }catch{}
}

const ready = computed(()=> !!settings.settings);
function iconSizeToPx(s: 'sm'|'md'|'lg'){ return s==='sm'?36: s==='lg'?60:48 }

function resetIconPx(){
  try{
    // 清除自定义像素，回到下拉框控制
    (settings.settings as any).iconPx = undefined;
  }catch{}
  settings.persist();
}

function resetColumns(){
  try{ settings.settings.columns = 5; }catch{}
  settings.persist();
}
function resetRadius(){
  try{ settings.settings.radius = 12; }catch{}
  settings.persist();
}
function resetCardOpacity(){
  try{ (settings.settings as any).cardOpacity = undefined; }catch{}
  settings.persist();
}
function resetContentMaxWidth(){
  try{ (settings.settings as any).contentMaxWidth = undefined; }catch{}
  settings.persist();
}

function setOpenMode(mode: 'current'|'newtab'){
  try{ settings.settings.openMode = mode; }catch{}
  settings.persist();
}
 
 

// 防抖持久化，优化滑块操作体验（略调高至400ms以减少写入）
const debouncedPersist = debounce(() => settings.persist(), 400);

async function doExport(){
  const blob = await exportBackup();
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  // 生成时间戳：YYYYMMDD-HHMM（本地时间）
  const d = new Date();
  const pad = (n:number)=> String(n).padStart(2,'0');
  const ts = `${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}`;
  a.download = `local-gce-backup_${ts}.json`;
  a.click();
  URL.revokeObjectURL(a.href);
}

async function doImport(e: Event){
  const file = (e.target as HTMLInputElement).files?.[0];
  if(!file) return;
  importFileName.value = file.name || '';
  const text = await file.text();
  try{
    await importBackup(text, { mode: 'merge' });
    // 重新初始化书签与分组，刷新主界面
    await bm.reload();
    await engines.reload();
    // 立即刷新设置到内存，确保背景等 UI 立刻生效
    try {
      const root = await getRoot();
      if (root?.settings) {
        (settings as any).settings = root.settings as any;
      }
    } catch {}
    // 导入后若存在其它分组且默认组(empty)则移除默认“未分组”
    try{
      const hasOthers = Array.isArray(bm.groups) && bm.groups.some(g => g.id !== 'default');
      const defaultEmpty = Array.isArray(bm.bookmarks) && !bm.bookmarks.some(b => (b.groupId ?? 'default') === 'default');
      if (hasOthers && defaultEmpty && bm.groups.some(g => g.id === 'default')) {
        await bm.removeGroup('default');
      }
    }catch{ /* 安全忽略 */ }
    try{ (window as any).gceToast?.('导入完成：已按 id 合并并覆盖重复项'); }catch{}
    emit('close');
  }catch(err:any){
    console.error('[import] failed:', err);
    try{ (window as any).gceToast?.(err?.message || '导入失败：文件不受支持或格式错误'); }catch{}
  }
}

async function applyBgUrl(){
  const url = (bgUrl.value||'').trim();
  if(!url) return;
  // 1) 直接支持 data URL（纯离线）
  if(/^data:image\//i.test(url)){
    settings.settings.backgroundDataUrl = url;
    await settings.persist();
    try{ (window as any).gceToast?.('已应用离线背景'); }catch{}
    return;
  }
  // 2) 支持 http(s) 图片：下载并转为 dataURL 存储
  if(/^https?:\/\//i.test(url)){
    try{
      const res = await fetch(url, { mode: 'cors' });
      if(!res.ok) throw new Error('网络响应异常');
      const blob = await res.blob();
      // 简单体积保护：超过 6MB 则提示过大
      if (blob.size > 6 * 1024 * 1024) {
        try{ (window as any).gceToast?.('图片过大（>6MB），请更换更小的图片'); }catch{}
        return;
      }
      const fr = new FileReader();
      fr.onload = async () => {
        try{
          const dataUrl = String(fr.result||'');
          if(!/^data:image\//i.test(dataUrl)) throw new Error('格式不支持');
          settings.settings.backgroundDataUrl = dataUrl;
          await settings.persist();
          try{ (window as any).gceToast?.('已应用网络图片并缓存为本地'); }catch{}
        }catch(e){
          try{ (window as any).gceToast?.('转换图片失败'); }catch{}
        }
      };
      fr.readAsDataURL(blob);
    }catch(e){
      try{ (window as any).gceToast?.('下载图片失败'); }catch{}
    }
    return;
  }
  try{ (window as any).gceToast?.('请输入 data:image/... 或 http(s) 图片地址'); }catch{}
}

async function clearBg(){
  settings.settings.backgroundDataUrl='';
  await settings.persist();
  bgFileName.value = '';
}

 
</script>
<style scoped>
  .mask{ position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:99990 }
  /* 浮动面板：锚定到左下角设置按钮上方 */
  .drawer{ position:fixed; left:16px; bottom:72px; top:auto; width:min(61vw, 620px); max-height:80vh; background:var(--glass-dark); backdrop-filter: blur(6px); border:1px solid var(--border); border-radius:14px; box-shadow: 0 18px 48px rgba(0,0,0,.45); z-index:99991; display:flex; flex-direction:column; overflow:hidden }
  .hdr{ display:flex; align-items:center; justify-content:space-between; padding:6px 16px; border-bottom:1px solid var(--border); background:var(--glass-dark); backdrop-filter: blur(4px) }
  /* 两栏布局 */
  .panel{ display:flex; min-height: 360px }
  .side{ width: 160px; border-right:1px solid var(--border); background:var(--glass-dark); padding:8px 6px; display:flex; flex-direction:column; gap:4px }
  .side .item{ text-align:left; height:34px; padding:0 10px; border-radius:10px; border:1px solid var(--border); background:var(--card); color:var(--text); cursor:pointer; display:flex; align-items:center }
  .side .item.on{ outline:2px solid var(--primary); border-color: transparent }
  .content{ flex:1; overflow:auto; padding:12px; display:flex; flex-direction:column; gap:14px; background:transparent }
  .sec{ border:1px solid var(--border); border-radius:var(--radius); padding:12px; background:var(--glass-dark); backdrop-filter: blur(4px) }
  .row{ display:flex; align-items:center; gap:10px; margin:8px 2px; flex-wrap:wrap }
  .row.col{ align-items:flex-start }
  .row.tight{ gap:8px }
  .row.tight label{ width:72px }
  .row label{ width:88px; color:var(--muted); padding-top:2px }
  .row input[type='range']{ flex:1 }
  .row input[type='text'], .row select{ flex:1; height:34px; border:1px solid var(--border); border-radius:10px; background:var(--card); color:var(--text); padding:0 10px }
  .row .url{ min-width: 0 }
  .row .actions{ display:flex; gap:10px; flex-wrap:nowrap }
  .btn{ height:30px; padding:0 10px; border-radius:10px; border:1px solid var(--border); background:var(--card); color:var(--text); cursor:pointer; white-space:nowrap; min-width:78px; display:inline-flex; align-items:center; justify-content:center }
  .btn.wide{ width:92px }
  .btn.solid{ background: var(--primary); color:#fff; border-color: transparent }
  .btn.outline{ background: var(--card) }
  .btn.reset{ min-width: 56px; padding: 0 8px }
  /* 作为按钮使用的超链接，移除下划线 */
  a.btn, a.btn:visited{ text-decoration: none; }
  a.btn:hover, a.btn:active, a.btn:focus{ text-decoration: none; }
  .muted{ color: var(--muted); font-size: 12px }
  .tip{ color: var(--muted); font-size: 12px; display:block; margin-top:6px }
  .import input[type='file'], .btn input[type='file']{ display:none }
  .filename{ flex:1; min-width:0; color: var(--muted); font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
  .close{ width:28px; height:28px; border:1px solid var(--border); border-radius:8px; background:var(--card); color:var(--text); cursor:pointer; display:inline-flex; align-items:center; justify-content:center }
  .close:hover{ filter: brightness(1.05) }

  /* 分段单选控件样式 */
  .seg{ display:inline-flex; background:var(--card); border:1px solid var(--border); border-radius:10px; overflow:hidden }
  .seg-item{ height:30px; padding:0 12px; background:transparent; color:var(--text); border:0; border-right:1px solid var(--border); cursor:pointer }
  .seg-item:last-child{ border-right:0 }
  .seg-item.on{ background: var(--primary); color:#fff }

  :host-context([data-theme='light']) .sec{ background: var(--glass-light); border-color: var(--border-light) }
.tabs2 .tab{ border:1px solid var(--border); background:var(--card); color:var(--text); padding:4px 10px; border-radius:8px; cursor:pointer }
.tabs2 .tab.on{ outline:2px solid var(--primary) }
.flex1{ flex:1 }
</style>
